import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: [],
  athButton: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}
function toLine(data) {
  return data.reduce((arr, { name, id, hideInMenu, parentId, path, icon, menuName, routes = [] }) =>
    arr.concat([{ name, id, hideInMenu, parentId, path, meta: { icon, title: menuName }}], toLine(routes)), [])
}
function toLineRoute(data) {
  return data.reduce((arr1, { name, path, redirect, meta, component, children = [] }) =>
    arr1.concat([{ name, path, redirect, component, meta: { activeMenu: meta.activeMenu }}], toLineRoute(children)), [])
}
function athList(devList, proList) {
  const arr1Ids = devList.map(item => item.name)
  const result = proList.filter(item => {
    if (arr1Ids.includes(item.name)) {
      const info = devList.find(dev => {
        if (dev.name === item.name) {
          return dev
        }
      })
      const ob = Object.assign(item.meta, info.meta)
      const ath = Object.assign(item, info)
      ath.meta = ob
      return ath
    }
  })
  return result
}
function toTree(data) {
  // 删除 所有 children,以防止多次调用
  data.forEach(function(item) {
    delete item.children
  })
  // 将数据存储为 以 id 为 KEY 的 map 索引数据列
  var map = {}
  data.forEach(function(item) {
    map[item.id] = item
  })
  var val = []
  data.forEach(function(item) {
    // 以当前遍历项，的pid,去map对象中找到索引的id
    var parent = map[item.parentId]
    // 好绕啊，如果找到索引，那么说明此项不在顶级当中,那么需要把此项添加到，他对应的父级中
    if (parent) {
      (parent.children || (parent.children = [])).push(item)
    } else {
      // 如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中，作为顶级
      val.push(item)
    }
  })
  return val
}
const actions = {
  generateRoutes({ commit }, info) {
    return new Promise(resolve => {
      const tree = toLine(info.menu)
      const route = toLineRoute(asyncRoutes)
      const newInfo = athList(route, tree)
      const accessedRoutes = toTree(newInfo)
      accessedRoutes.push({ path: '*', redirect: '/404', hideInMenu: true })
      commit('SET_ROUTES', accessedRoutes)
      // const accessedRoutes = asyncRoutes
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
